//
//  String+YHExtension.swift
//  Adorbee
//
//  Created by amovision on 2024/11/26.
//

import CoreGraphics
import UIKit

public extension String {
  var pointer: UnsafeRawPointer {
    return UnsafeRawPointer(bitPattern: abs(hashValue))!
  }

  var mutablePointer: UnsafeMutableRawPointer {
    return UnsafeMutableRawPointer(bitPattern: abs(hashValue))!
  }

  var ns: NSString { self as NSString }
  var local: String {
    NSLocalizedString(self, comment: "")
  }

  var uncapitalized: String {
      guard !isEmpty else { return self }
      return String(prefix(1)).lowercased() + dropFirst()
  }

  func width(_ font: UIFont?, mode: NSLineBreakMode = .byWordWrapping) -> CGFloat {
    size(for: font == nil ? nil : [NSAttributedString.Key.font: font!], mode: mode).width
  }

  func height(_ font: UIFont?, width: CGFloat, mode: NSLineBreakMode = .byWordWrapping) -> CGFloat {
    size(for: font == nil ? nil : [NSAttributedString.Key.font: font!], size: CGSizeMake(width, .infinity), mode: mode).height
  }

  var fileURL: URL {
    URL(fileURLWithPath: self)
  }

  func urlEncode(_ charSet: CharacterSet) -> String? {
    addingPercentEncoding(withAllowedCharacters: charSet)!
  }

  func urlDecode() -> String {
    removingPercentEncoding ?? self
  }

  func size(for attributes: [NSAttributedString.Key: Any]?, size: CGSize = CGSizeMake(.infinity, .infinity), mode: NSLineBreakMode = .byWordWrapping) -> CGSize {
    var attrs: [NSAttributedString.Key: Any] = attributes ?? [.font: UIFont.systemFont(ofSize: 17)]
    if mode != .byWordWrapping {
      let paragraphStyle = NSMutableParagraphStyle()
      paragraphStyle.lineBreakMode = mode
      attrs[.paragraphStyle] = paragraphStyle
    }
    let rect = ns.boundingRect(with: size, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil)
    return CGSizeMake(ceil(rect.width), ceil(rect.height))
  }
}

public extension String {
  init(_ format: String, _ args: CVarArg ...) {
    self.init(format: format, args)
  }

  static func format(_ format: String, _ args: CVarArg ...) -> String {
    return String(format: format, args)
  }
}
